#ifndef MOONLIGHT_OHOS_ABSTRACTTOUCHSCREENCONTROLHANDLER_H
#define MOONLIGHT_OHOS_ABSTRACTTOUCHSCREENCONTROLHANDLER_H

#include <ace/xcomponent/native_interface_xcomponent.h>
#include <string>
#include <sstream>

class AbstractTouchScreenControlHandler {
protected:
    using TouchEvent = OH_NativeXComponent_TouchEvent;
    using TouchPoint = OH_NativeXComponent_TouchPoint;
    using ToolType = OH_NativeXComponent_TouchPointToolType;

public:
    using Config = std::unordered_map<std::string, std::string>;
    virtual void handle(OH_NativeXComponent *const xcomp, void *const win, const TouchEvent &touchEvent) = 0;

protected:
    virtual void applyConfig(const Config &overrides) = 0;

public:
    virtual ~AbstractTouchScreenControlHandler() {};

protected:
    template<typename V>
    static V getOrDefault(const std::unordered_map<std::string, std::string> &map,
            const std::string &key, const V &dft) {
        std::string s = std::to_string(dft);
        if (map.contains(key)) {
            s = map.at(key);
        }
        std::stringstream ss(s);
        V v;
        ss >> v;
        return v;
    }
};

#define ATSCH_DEFINE_CONFIG(type, key, dft) \
    type key = dft; \
    static constexpr type key##Default = dft;

#define ATSCH_EXTRACT_CONFIG(key) \
    key = AbstractTouchScreenControlHandler::getOrDefault<decltype(key)>(overrides, #key, key##Default); \
    if constexpr (DEBUG) { \
        OH_LOG_DEBUG(LOG_APP, "Setting config %{public}s to %{public}s", #key, std::to_string(key).c_str()); \
    }

#endif //MOONLIGHT_OHOS_ABSTRACTTOUCHSCREENCONTROLHANDLER_H
